using System;
using System.Collections.Generic;
using PickGold.Charting;

namespace PickGold.Charting.Formulas
{
	internal static class FormulaHelper
	{
		internal static IList<DataField> GetDataFields(SeriesChartType chartType)
		{
			switch (chartType)
			{
				case SeriesChartType.Stock:
				case SeriesChartType.Candlestick:
					return new DataField[] { DataField.High, DataField.Low, DataField.Open, DataField.Close };

				case SeriesChartType.Range:
				case SeriesChartType.SplineRange:
				case SeriesChartType.RangeBar:
				case SeriesChartType.RangeColumn:
					return new DataField[] { DataField.Top, DataField.Bottom };

				case SeriesChartType.ErrorBar:
					return new DataField[] { DataField.Center, DataField.LowerError, DataField.UpperError };

				case SeriesChartType.BoxPlot:
					return new DataField[] { DataField.LowerWisker, DataField.UpperWisker, DataField.LowerBox, DataField.UpperBox, DataField.Average, DataField.Median };

				case SeriesChartType.Bubble:
					return new DataField[] { DataField.Bubble, DataField.BubbleSize };
			}
			return new DataField[] { DataField.Y };
		}

		internal static SeriesChartType GetDefaultChartType(DataField field)
		{
			switch (field)
			{
				case DataField.LowerWisker:
				case DataField.UpperWisker:
				case DataField.LowerBox:
				case DataField.UpperBox:
				case DataField.Average:
				case DataField.Median:
					return SeriesChartType.BoxPlot;

				case DataField.Bubble:
				case DataField.BubbleSize:
					return SeriesChartType.Bubble;

				case DataField.High:
				case DataField.Low:
				case DataField.Open:
				case DataField.Close:
					return SeriesChartType.Stock;

				case DataField.Center:
				case DataField.LowerError:
				case DataField.UpperError:
					return SeriesChartType.ErrorBar;

				case DataField.Top:
				case DataField.Bottom:
					return SeriesChartType.Range;
			}
			return SeriesChartType.Line;
		}

		internal static FormulaInfo GetFormulaInfo(FinancialFormula formula)
		{
			switch (formula)
			{
				case FinancialFormula.AccumulationDistribution:
					return new AccumulationDistributionFormulaInfo();

				case FinancialFormula.AverageTrueRange:
					return new AverageTrueRangeFormulaInfo();

				case FinancialFormula.BollingerBands:
					return new BollingerBandsFormulaInfo();

				case FinancialFormula.ChaikinOscillator:
					return new ChaikinOscillatorFormulaInfo();

				case FinancialFormula.CommodityChannelIndex:
					return new CommodityChannelIndexFormulaInfo();

				case FinancialFormula.DetrendedPriceOscillator:
					return new DetrendedPriceOscillatorFormulaInfo();

				case FinancialFormula.EaseOfMovement:
					return new EaseOfMovementFormulaInfo();

				case FinancialFormula.Envelopes:
					return new EnvelopesFormulaInfo();

				case FinancialFormula.ExponentialMovingAverage:
					return new ExponentialMovingAverageFormulaInfo();

				case FinancialFormula.Forecasting:
					return new ForecastingFormulaInfo();

				case FinancialFormula.MovingAverageConvergenceDivergence:
					return new MovingAverageConvergenceDivergenceFormulaInfo();

				case FinancialFormula.MassIndex:
					return new MassIndexFormulaInfo();

				case FinancialFormula.MedianPrice:
					return new MedianPriceFormulaInfo();

				case FinancialFormula.MoneyFlow:
					return new MoneyFlowFormulaInfo();

				case FinancialFormula.NegativeVolumeIndex:
					return new NegativeVolumeIndexFormulaInfo();

				case FinancialFormula.OnBalanceVolume:
					return new OnBalanceVolumeFormulaInfo();

				case FinancialFormula.Performance:
					return new PerformanceFormulaInfo();

				case FinancialFormula.PositiveVolumeIndex:
					return new PositiveVolumeIndexFormulaInfo();

				case FinancialFormula.PriceVolumeTrend:
					return new PriceVolumeTrendFormulaInfo();

				case FinancialFormula.RateOfChange:
					return new RateOfChangeFormulaInfo();

				case FinancialFormula.RelativeStrengthIndex:
					return new RelativeStrengthIndexFormulaInfo();

				case FinancialFormula.MovingAverage:
					return new MovingAverageFormulaInfo();

				case FinancialFormula.StandardDeviation:
					return new StandardDeviationFormulaInfo();

				case FinancialFormula.StochasticIndicator:
					return new StochasticIndicatorFormulaInfo();

				case FinancialFormula.TriangularMovingAverage:
					return new TriangularMovingAverageFormulaInfo();

				case FinancialFormula.TripleExponentialMovingAverage:
					return new TripleExponentialMovingAverageFormulaInfo();

				case FinancialFormula.TypicalPrice:
					return new TypicalPriceFormulaInfo();

				case FinancialFormula.VolatilityChaikins:
					return new VolatilityChaikinsFormulaInfo();

				case FinancialFormula.VolumeOscillator:
					return new VolumeOscillatorFormulaInfo();

				case FinancialFormula.WeightedClose:
					return new WeightedCloseFormulaInfo();

				case FinancialFormula.WeightedMovingAverage:
					return new WeightedMovingAverageFormulaInfo();

				case FinancialFormula.WilliamsR:
					return new WilliamsRFormulaInfo();
			}
			return null;
		}

		internal static DataField? MapFormulaDataField(SeriesChartType chartType, DataField formulaField)
		{
			switch (formulaField)
			{
				case DataField.High:
				case DataField.Top:
					switch (chartType)
					{
						case SeriesChartType.Stock:
						case SeriesChartType.Candlestick:
							return (DataField)10;

						case SeriesChartType.Range:
						case SeriesChartType.SplineRange:
						case SeriesChartType.RangeBar:
						case SeriesChartType.RangeColumn:
							return (DataField)0x11;

						case SeriesChartType.ErrorBar:
							return (DataField)0x10;

						case SeriesChartType.BoxPlot:
							return (DataField)5;
					}
					break;

				case DataField.Low:
				case DataField.Bottom:
					switch (chartType)
					{
						case SeriesChartType.Stock:
						case SeriesChartType.Candlestick:
							return (DataField)11;

						case SeriesChartType.Range:
						case SeriesChartType.SplineRange:
						case SeriesChartType.RangeBar:
						case SeriesChartType.RangeColumn:
							return (DataField)0x12;

						case SeriesChartType.Radar:
						case SeriesChartType.Polar:
							goto Label_00CA;

						case SeriesChartType.ErrorBar:
							return (DataField)15;

						case SeriesChartType.BoxPlot:
							return (DataField)4;
					}
					goto Label_00CA;

				case DataField.Open:
					switch (chartType)
					{
						case SeriesChartType.Stock:
						case SeriesChartType.Candlestick:
							return (DataField)12;

						case SeriesChartType.Range:
						case SeriesChartType.SplineRange:
						case SeriesChartType.RangeBar:
						case SeriesChartType.RangeColumn:
							return (DataField)0x12;

						case SeriesChartType.Radar:
						case SeriesChartType.Polar:
							goto Label_0129;

						case SeriesChartType.ErrorBar:
							return (DataField)14;

						case SeriesChartType.BoxPlot:
							return (DataField)6;
					}
					goto Label_0129;

				case DataField.Close:
				case DataField.Y:
					switch (chartType)
					{
						case SeriesChartType.Stock:
						case SeriesChartType.Candlestick:
							return (DataField)13;

						case SeriesChartType.Range:
						case SeriesChartType.SplineRange:
						case SeriesChartType.RangeBar:
						case SeriesChartType.RangeColumn:
							return (DataField)0x11;

						case SeriesChartType.Radar:
						case SeriesChartType.Polar:
							goto Label_018D;

						case SeriesChartType.ErrorBar:
							return (DataField)14;

						case SeriesChartType.BoxPlot:
							return (DataField)6;

						case SeriesChartType.Bubble:
							return (DataField)8;
					}
					goto Label_018D;

				default:
					return null;
			}
			return null;
		Label_00CA:
			return null;
		Label_0129:
			return null;
		Label_018D:
			return (DataField)1;
		}
	}
}

